package com.budwk.app.sqfwDoc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.budwk.app.exception.ServiceException;
import com.budwk.app.sqfwDoc.models.SqfwTemplateDict;
import com.budwk.app.sqfwDoc.models.SqfwTemplateField;
import com.budwk.app.sqfwDoc.models.SqfwTemplateFieldRelation;
import com.budwk.app.sqfwDoc.service.SqfwTemplateFieldRelationService;
import com.budwk.app.sqfwDoc.service.SqfwTemplateFieldService;
import com.budwk.app.sqfwDoc.service.SqfwTemplateDictService;
import com.budwk.app.sqfwDoc.vo.SqfwTemplateDictSimpleVO;
import com.budwk.app.sqfwDoc.vo.SqfwTemplateDictTreeVO;
import com.budwk.starter.database.service.BaseServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.trans.Trans;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author ZY.Wang
 * @since 2023/12/5
 */
@IocBean(args = {"refer:dao"})
public class SqfwTemplateDictServiceImpl extends BaseServiceImpl<SqfwTemplateDict> implements SqfwTemplateDictService {
    public SqfwTemplateDictServiceImpl(Dao dao) {
        super(dao);
    }

    @Inject
    private SqfwTemplateFieldService sqfwTemplateFieldService;
    @Inject
    private SqfwTemplateFieldRelationService sqfwTemplateFieldRelationService;

    @Inject

    @Override
    public List<SqfwTemplateDictTreeVO> listDictTree() {
        List<SqfwTemplateDictTreeVO> resultList = Lists.newArrayList();

        Map<String, List<SqfwTemplateDict>> preAllMap = getAllSimpleMap();
        for (SqfwTemplateDictTreeVO parentDict : getRootNode(preAllMap)) {
            List<SqfwTemplateDictTreeVO> childrenDict = buildChildren(parentDict, preAllMap);
            parentDict.setExpanded(childrenDict.size() > 0);
            parentDict.setChildren(childrenDict);
            resultList.add(parentDict);
        }

        return resultList;
    }

    @Override
    public List<SqfwTemplateDict> listDictByParentId(String parentId) {
        if (StringUtils.isBlank(parentId)) parentId = "0";
        Cnd cnd = Cnd.NEW();
        cnd.and(SqfwTemplateDict::getParentId, "=", parentId);
        return query(cnd);
    }

    @Override
    public SqfwTemplateDictSimpleVO getDetail(String id) {
        SqfwTemplateDict dict = fetch(id);
        if (dict == null) return null;

        SqfwTemplateDictSimpleVO resultVO = new SqfwTemplateDictSimpleVO();

        String parentId = dict.getParentId();
        SqfwTemplateDict parentPerform = fetch(parentId);
        resultVO.setParentName(parentPerform.getDictName());

        String templateFieldId = dict.getTemplateFieldId();
        resultVO.setTemplateField(sqfwTemplateFieldService.fetch(templateFieldId));

        return resultVO;
    }

    @Override
    public void addDict(String userId, SqfwTemplateDict data) {
        String templateFieldId = data.getTemplateFieldId();
        SqfwTemplateField field = sqfwTemplateFieldService.fetch(templateFieldId);
        if (field == null) throw new ServiceException("字段选取数据有误");

        if (StringUtils.isBlank(data.getParentId())) data.setParentId("0");
        data.setCreateBy(userId);
        data.setCreateTime(new Date());
        data.setUpdateBy(userId);
        data.setUpdateTime(new Date());
        insert(data);

        // 要往关系映射表中插入数据
        SqfwTemplateFieldRelation relation = new SqfwTemplateFieldRelation();
        relation.setTemplateDictId(data.getId());
        relation.setTemplateFieldId(templateFieldId);
        relation.setCreateTime(new Date());
        relation.setCreateBy(userId);
        relation.setUpdateBy(userId);
        relation.setUpdateTime(new Date());
        sqfwTemplateFieldRelationService.insert(relation);
    }

    @Override
    public void updateDict(String userId, SqfwTemplateDict data) {
        Trans.exec(() -> {
            // 首先查出之前绑定的数据，然后进行更改
            Cnd relationCND = Cnd.NEW();
            relationCND.and(SqfwTemplateFieldRelation::getTemplateDictId, "=", data.getId());
            SqfwTemplateFieldRelation relation = sqfwTemplateFieldRelationService.fetch(relationCND);
            if (relation != null) {
                relation.setTemplateFieldId(data.getTemplateFieldId());
                relation.setUpdateBy(userId);
                relation.setUpdateTime(new Date());
                sqfwTemplateFieldRelationService.updateIgnoreNull(relation);
            }else {
                relation = new SqfwTemplateFieldRelation();
                relation.setTemplateFieldId(data.getTemplateFieldId());
                relation.setTemplateDictId(data.getId());
                relation.setCreateBy(userId);
                relation.setUpdateBy(userId);
                relation.setCreateTime(new Date());
                relation.setUpdateTime(new Date());
                sqfwTemplateFieldRelationService.insert(relation);
            }

            data.setUpdateBy(userId);
            data.setUpdateTime(new Date());
            updateIgnoreNull(data);
        });
    }

    @Override
    public void deleteDict(String id) {
        Trans.exec(() -> {
            // 删除映射关系中的数据
            SqfwTemplateDict dict = fetch(id);
            if (dict == null) throw new ServiceException("数据不存在");

            Cnd relationCnd = Cnd.NEW();
            relationCnd.and(SqfwTemplateFieldRelation::getTemplateFieldId, "=", dict.getTemplateFieldId())
                    .and(SqfwTemplateFieldRelation::getTemplateDictId, "=", dict.getId());
            Set<String> preDeleteIdSet = sqfwTemplateFieldRelationService.query(relationCnd).stream().map(SqfwTemplateFieldRelation::getId).collect(Collectors.toSet());
            sqfwTemplateFieldRelationService.delete(Lists.newArrayList(preDeleteIdSet));

            // 删除字典
            delete(id);
        });
    }

    //---------下面时一些私有的方法------------------------------------
    private List<SqfwTemplateDictTreeVO> buildChildren(SqfwTemplateDictTreeVO parentDict, Map<String, List<SqfwTemplateDict>> preAllMap) {
        List<SqfwTemplateDictTreeVO> childrenList = Lists.newArrayList();

        List<SqfwTemplateDict> dictList = preAllMap.get(parentDict.getId());
        if (dictList != null) {
            for (SqfwTemplateDict dict : dictList) {
                if (dict.getParentId().equals(parentDict.getId())) {
                    SqfwTemplateDictTreeVO vo = new SqfwTemplateDictTreeVO();
                    BeanUtil.copyProperties(dict, vo);

                    if (StringUtils.isNotBlank(vo.getTemplateFieldId())) {
                        SqfwTemplateField field = sqfwTemplateFieldService.fetch(vo.getTemplateFieldId());
                        vo.setDictCode(field.getFieldCode());
                    }

                    List<SqfwTemplateDictTreeVO> children = buildChildren(vo, preAllMap);
                    vo.setChildren(children);
                    vo.setExpanded(children.size() > 0);
                    childrenList.add(vo);
                }
            }
        }
        return childrenList;
    }

    private List<SqfwTemplateDictTreeVO> getRootNode(Map<String, List<SqfwTemplateDict>> preAllMap) {
        List<SqfwTemplateDictTreeVO> rootList = Lists.newArrayList();
        List<SqfwTemplateDict> dictList = preAllMap.get("0");
        if (dictList == null || dictList.size() == 0) return rootList;
        for (SqfwTemplateDict dict : dictList) {
            String parentId = dict.getParentId();
            if (parentId.equals("0")) {
                SqfwTemplateDictTreeVO vo = new SqfwTemplateDictTreeVO();
                BeanUtil.copyProperties(dict, vo);

                if (StringUtils.isNotBlank(vo.getTemplateFieldId())) {
                    SqfwTemplateField field = sqfwTemplateFieldService.fetch(vo.getTemplateFieldId());
                    vo.setDictCode(field.getFieldCode());
                }

                rootList.add(vo);
            }
        }
        return rootList;
    }

    /**
     * 根据所有的数据生成一个简单的树
     *
     * @return 返回的结果
     */
    private Map<String, List<SqfwTemplateDict>> getAllSimpleMap() {
        List<SqfwTemplateDict> allList = query();

        Map<String, List<SqfwTemplateDict>> resultMap = Maps.newHashMap();
        for (SqfwTemplateDict dict : allList) {
            String parentId = dict.getParentId();
            if (StringUtils.isBlank(parentId)) parentId = "0";

            if (resultMap.containsKey(parentId)) {
                resultMap.get(parentId).add(dict);
            } else {
                resultMap.put(parentId, Lists.newArrayList(dict));
            }
        }
        return resultMap;
    }

}
